package com.chenyue.cm.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chenyue.cm.base.bean.Pageable;
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Origin
 * modify By LBX
 */
public class RequestUtil {


    public static Pageable getPageable(HttpServletRequest request) {

        String searchString = request.getParameter(pageInfo.SEARCH_PARAM.value);
        Map<String, Object> resultMap = JSON.parseObject(searchString, HashMap.class);

        int page = 1;
        int pageSize = 10;

        if (StringUtils.isNotEmpty(request.getParameter(pageInfo.ROWS.value))) {
            pageSize = Integer.parseInt(request.getParameter(pageInfo.ROWS.value));
        }

        if (StringUtils.isNotBlank(request.getParameter(pageInfo.PAGE.value))) {
            return new Pageable(Integer.parseInt(request.getParameter(pageInfo.PAGE.value)), pageSize, resultMap);
        } else {
            return new Pageable(page, pageSize, resultMap);
        }

    }

    /**
     * @param request 请求体
     * @return 返回JSON数据包
     */
    public static String getJsonString(HttpServletRequest request) {
        String json = "";
        try {
            ServletInputStream in = request.getInputStream();
            //把流转化成字符串
            String content = IOUtils.toString(in, StandardCharsets.UTF_8);
            //发送的时候使用URLEncoder.encode编码，接收的时候使用URLDecoder.decode解码，都按指定的编码格式进行编码、解码，可以保证不会出现乱码
            json = URLDecoder.decode(content, StandardCharsets.UTF_8.name());
            //
            json = json.substring(json.indexOf("=") + 1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
    }

    enum pageInfo {
        /**
         * 查询参数map
         */
        SEARCH_PARAM("searchParam"),
        /**
         * 页数
         */
        PAGE("pageNum"),
        /**
         * 每页条数
         */
        ROWS("pageSize");

        String value;

        pageInfo(String value) {
            this.value = value;
        }
    }

    /**
     * 从http请求中 获取请求参数 封装成map返回
     *
     * @param request
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static HashMap<String, Object> getParamMap(HttpServletRequest request) {

        HashMap<String, Object> resultMap = new HashMap<String, Object>();

        Enumeration em = request.getParameterNames();
        while (em.hasMoreElements()) {
            String name = (String) em.nextElement();
            String value = request.getParameter(name);
            resultMap.put(name, value);
        }

        return resultMap;
    }


    /**
     * 从http请求中 获取请求参数 封装成map返回
     *
     * @param request
     * @return
     *//*
	@SuppressWarnings("rawtypes")
	public static Map<String, Object> getQueryParamMap(HttpServletRequest request) {

		Map<String, Object> resultMap = new HashMap<String, Object>();

		Enumeration em = request.getParameterNames();
		while (em.hasMoreElements()) {
			String name = (String) em.nextElement();
			String value = request.getParameter(name);
			if (name.startsWith("SEARCH_")&&value!=""&&value!=null) {
				resultMap.put(name, value);
			}
		}

		return resultMap;
	}*/
    public static String getSearchSql_(HttpServletRequest request,
                                       String mainsql) {
        String name = request.getParameter("key");
        String type = request.getParameter("type");
        String value = request.getParameter("value");
        if (name != null && name != "null") {
            mainsql += "where " + name + " "
                    + ("0".equals(type) ? "like " : "=") + " " + " '"
                    + ("0".equals(type) ? "%" + value + "%" : value) + "'";
        }
        return mainsql;

    }

    /**
     * 转至：https://my.oschina.net/u/994081/blog/185982
     */
    /**
     * 根据 httpServletRequest 获取请求的ip地址信息
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0
                    || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0
                    || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0
                    || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        // Logger.error("获取ip异常：{}");
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        // ipAddress = this.getRequest().getRemoteAddr();

        return ipAddress;
    }


    /**
     * 获取Ip地址
     *
     * @param request
     * @return
     */
    public static String getIpAdrress(HttpServletRequest request) {
        String Xip = request.getHeader("X-Real-IP");
        String XFor = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = XFor.indexOf(",");
            if (index != -1) {
                return XFor.substring(0, index);
            } else {
                return XFor;
            }
        }
        XFor = Xip;
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            return XFor;
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getRemoteAddr();
        }
        return XFor;
    }


    public static String getSearchSql(HttpServletRequest request) {
        String keys = " where 1=1 ";
        String sord = request.getParameter("sord");// 排序方式
        String sidx = request.getParameter("sidx");// 排序列名
        String id = request.getParameter("id");// 排序列名
        Boolean search = (request.getParameter("_search").equals("true")) ? true
                : false;// 是否用于查询请求
        if (id != null) {
            keys += " AND  id = " + id + " ";// 查询条件字符串
        }
        if (search) {

            String filters = request.getParameter("filters");// 具体的条件
            if (filters != null && !"".equals(filters)) {
                keys += " AND ( ";// 将从表自身的检索条件用AND（条件1 AND 条件2 OR 条件3...）的形式封装
                System.out.println("filters=" + filters);
                // 传入数据的格式是类似这样的："{"groupOp":"AND","rules":[{"field":"id","op":"eq","data":"1"},{"field":"type","op":"ew","data":"2"}]}"
//				JSONObject jsonObject = JSONObject.fromObject(filters);
                JSONObject jsonObject = null;
                String groupOp = "AND";// 每个规则之间的关系（and/or）
                if (jsonObject.getString("groupOp") != null
                        && !"".equals(jsonObject.getString("groupOp"))) {
                    if (jsonObject.getString("groupOp").equals("OR")) {
                        groupOp = "OR";
                    }
                }

                JSONArray rulesjson = jsonObject.getJSONArray("rules");
                // 遍历每个条件
                for (int z = 0; z < rulesjson.size(); z++) {
                    Object t = rulesjson.get(z);
//					JSONObject rulejson = JSONObject.fromObject(t);
                    JSONObject rulejson = null;
                    String field = rulejson.getString("field");
                    String op = rulejson.getString("op");
                    String data = rulejson.getString("data");
                    String string = "";// 用于存储单个条件sql语句片段
                    // 开始转化为sql语句
                    switch (op) {
                        case "eq":// 相等
                            string = " = '" + data + "' ";
                            break;
                        case "ne":// 不相等
                            string = " <> '" + data + "' ";
                            break;
                        case "li":// 小于
                            string = " < '" + data + "' ";
                            break;
                        case "le":// 小于等于
                            string = " <= '" + data + "' ";
                            break;
                        case "gt":// 大于
                            string = " > '" + data + "' ";
                            break;
                        case "ge":// 大于等于
                            string = " >= '" + data + "' ";
                            break;
                        case "bw":// 在...之间
                        {
                            if (data.split(",").length == 2) {
                                string = " BETWEEN '" + data.split(",")[0]
                                        + "' AND '" + data.split(",")[1] + "' ";
                            } else {
                                string = " = '" + data + "' ";// 数据错误时处理
                            }
                        }

                        break;
                        case "bn":// 不在...之间
                        {
                            if (data.split(",").length == 2) {
                                string = " NOT BETWEEN '" + data.split(",")[0]
                                        + "' AND '" + data.split(",")[1] + "' ";
                            } else {
                                string = " <> '" + data + "' ";// 数据错误时处理
                            }
                        }
                        break;
                        case "ew":// 以...结束
                            string = " LIKE '%" + data + "' ";
                            break;
                        case "en":// 不以...结束
                            string = " NOT LIKE '%" + data + "' ";
                            break;
                        case "cn":// 包含
                            string = " LIKE '%" + data + "%' ";
                            break;
                        case "nc":// 不包含
                            string = " NOT LIKE '%" + data + "%' ";
                            break;
                        case "in":// 在
                        {
                            string = " IN ( ";
                            String[] datas = data.split(",");
                            for (int i = 0; i < datas.length; i++) {
                                string += " '" + datas[i] + "' ";
                                if (i != datas.length - 1) {
                                    string += ",";
                                } else {
                                    string += " ) ";
                                }
                            }
                        }
                        break;
                        case "ni":// 不在
                        {
                            string = " NOT IN ( ";
                            String[] datas = data.split(",");
                            for (int i = 0; i < datas.length; i++) {
                                string += " '" + datas[i] + "' ";
                                if (i != datas.length - 1) {
                                    string += ",";
                                } else {
                                    string += " ) ";
                                }
                            }
                        }
                        break;
                        default:
                            op = null;
                            System.out.println("OP符号错误");// OP符号错误
                    }
                    if (op != null) {
                        if (z == rulesjson.size() - 1) {
                            keys += " " + field + " " + string + " ";
                        } else {
                            keys += " " + field + " " + string + " " + groupOp
                                    + " ";
                        }

                    }
                }
                keys += "  ) ";
            }

        }
        // 升降序SQL语句转换
        if (sidx != null && !"".equals(sidx)) {
            System.out.println(sidx);
            keys += " ORDER BY " + sidx;
            System.out.println("sord=" + sord);
            if (!sord.equals("asc")) {
                keys += " DESC ";
            }
        }
        return keys;
    }


    //add by liangc >>>>>>>>>>>>>>
    public static void writeStringToResponse(String str, HttpServletResponse response) throws Exception {
        writeStringToResponse(str, response, "text/json");
    }

    public static void writeStringToResponse(String str, HttpServletResponse response, String contentType) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType(contentType);
        try {
            OutputStream os = response.getOutputStream();
            IOUtils.write(str, os);
        } catch (IOException e) {
            throw new Exception("写入 response 失败 : ", e);
        }
    }

    public static void writeStringToResponse(Object obj, HttpServletResponse response) throws Exception {
        writeStringToResponse(obj.toString(), response);
    }


}
